#pragma once
#include <iostream>
#include <functional>
#include <memory>
#include <sys/types.h>
#include <sys/wait.h>
#include "Socket.hpp"

namespace TcpSeverModule
{
    using namespace SocketModule;
    using tcphandle_t = std::function<bool(sockptr, InetAddr)>;
    class TcpSever
    {
    public:
        TcpSever(int port) : _port(port), _isrunning(false)
        {
            _listensock = std::make_unique<TcpSocket>();
        }
        void TcpInit(tcphandle_t handle)
        {
            _handle = handle;
            _listensock->BuildTcpSocket(_port);
        }
        void Loop()
        {
            _isrunning = true;
            while (true)
            {
                // 1. 接收连接
                InetAddr client;
                sockptr sockfd = _listensock->Accept(&client);
                if (sockfd == nullptr)
                {
                    continue;
                }
                // 2. 处理连接
                LOG(LogLevel::INFO) << "accept a new client" << client.Addr();
                pid_t id = fork();
                if (id == 0)
                {
                    _listensock->Close();
                    if (fork() > 0)
                        exit(0);
                    _handle(sockfd, client);
                    exit(0);
                }
                sockfd->Close();
                waitpid(id, nullptr, 0);
            }
            _isrunning = false;
        }
        ~TcpSever()
        {
            if (_listensock)
            {
                _listensock->Close();
            }
        }

    private:
        int _port;
        std::unique_ptr<Socket> _listensock;
        bool _isrunning;
        tcphandle_t _handle;
    };
}